// #include <iostream>
// #include <unistd.h>
// #include <signal.h>

// 自定义捕捉信号
//  void Handler(int signo)
//  {
//  	// 当对应的信号被触发，内核将对应的信号编号传递给自定义方法
//  	std::cout << "get a signal,signal number is : " << signo << std::endl;
//  }

// int main()
// {
// 	for (int signo = 1; signo < 32; signo++)
// 	{
// 		signal(signo, Handler);
// 		std::cout << "自定义捕捉信号 : " << signo << std::endl;
// 	}

// 	while (true)
// 	{
// 		std::cout << "hello world" << std::endl;
// 		sleep(1);
// 	}
// 	return 0;
// }

// 模拟kill命令
//  #include <iostream>
//  #include <cstdlib>
//  #include <signal.h>
//  #include <string>
//  void Usage(std::string pore)
//  {
//  	std::cout << "Usage: " << pore << " signumber processid" << std::endl;
//  }
//  // ././kill 9 123
//  int main(int argc,char* argv[])
//  {
//  	if(argc != 3)
//  	{
//  		Usage(argv[0]);
//  		exit(1);
//  	}
//  	int signumber = std::stoi(argv[1]);
//  	pid_t prcessid = std::stoi(argv[2]);
//  	int n = ::kill(prcessid,signumber);
//  	if(n < 0)
//  	{
//  		perror("kill");
//  		exit(2);
//  	}
//  	return 0;
//  }

// 演示raise ，给自己发信号
//  #include <iostream>
//  #include <unistd.h>
//  #include <signal.h>

// int main()
// {
// 	int cnt = 5;
// 	while(true)
// 	{
// 		std::cout << "我还活着" << std::endl;
// 		cnt--;
// 		std::cout << cnt << std::endl;
// 		raise(9);//给自己发送九信号
// 		sleep(1);
// 	}
// 	return 0;
// }

// abort 自己给自己发6号信号
// #include <iostream>
// #include <unistd.h>
// #include <signal.h>

// int main()
// {
// 	int cnt = 5;
// 	while(true)
// 	{
// 		std::cout << "我还活着" << std::endl;
// 		cnt--;
// 		std::cout << cnt << std::endl;
// 		abort();//给自己发送九信号
// 		sleep(1);
// 	}
// 	return 0;
// }

// alarm 给自己设置一个闹钟，收到14号信号
//  (1) cout一下就会进行一次IO，次数多
//  #include <iostream>
//  #include <unistd.h>

// int main()
// {
// 	//统计我的服务器1s中可以将计数器累计多少！ IO多 我的服务器大约14万次
// 	int number = 0;
// 	alarm(1);//给我的程序设置一个一秒的闹钟，1s后自己会收到一个（14）SIGALRM 的信号

// 	while(true)
// 	{
// 		std::cout << number++ << std::endl;
// 	}
// 	return 0;
// }

// （2） 减少cout IO操作
//  #include <iostream>
//  #include <unistd.h>
//  #include <signal.h>

// int number = 0;

// void di(int signo)
// {
// 	//IO少只有一次，4亿多
// 	std:: cout << number << " " << signo << std::endl;
// 	exit(1);
// }

// int main()
// {
// 	//统计我的服务器1s中可以将计数器累计多少！
// 	alarm(1);//给我的程序设置一个一秒的闹钟，1s后自己会收到一个（14）SIGALRM 的信号
// 	signal(SIGALRM,di);
// 	while(true)
// 	{
// 		number++;
// 	}
// 	return 0;
// }

// 设置取消闹钟
//  #include <iostream>
//  #include <unistd.h>

// int main()
// {
// 	alarm(5);
// 	sleep(1);
// 	int n = alarm(0);//设置为0，默认就算被认为取消闹钟，返回值为闹钟还剩多少时间
// 	std::cout << "n: " << n << std::endl;
// 	return 0;
// }


//设置重复闹钟来执行任务
// #include <iostream>
// #include <unistd.h>
// #include <signal.h>
// #include <functional>
// #include <vector>

// using func_t = std::function<void()>;

// std::vector<func_t> n;

// int number = 0;

// void hanlder(int signo)
// {
// 	for (auto &f : n)
// 	{
// 		f();
// 	}
// 	std::cout << number << std::endl;
// 	alarm(1);
// }

// int main()
// {
// 	n.push_back([]()
// 				{ std::cout << "我是日志任务" << std::endl; });
// 	n.push_back([]()
// 				{ std::cout << "我是下载任务" << std::endl; });
// 	n.push_back([]()
// 				{ std::cout << "我是MYSql任务" << std::endl; });

// 	alarm(1);

// 	signal(SIGALRM, hanlder);
// 	while (true)
// 	{
// 		pause();//等待一个信号，阻塞
// 	}
// 	return 0;
// }


//模拟野指针,程序运行发生段错误，OS给进程发送（11）SIGSEGV 来杀死进程
// #include <iostream>
// #include <signal.h>

// void helder(int signo)
// {
// 	std::cout << signo << std::endl;
// }

// int main()
// {
// 	signal(SIGSEGV,helder);
// 	int *p = nullptr;
// 	*p = 100;

// 	while(true)
// 	return 0;
// }

//模拟除0异常，OS给进程发送（8）SIGFPE 来杀死进程 浮点数异常
// #include <iostream>
// #include <signal.h>

// void helder(int signo)
// {
// 	std::cout << signo << std::endl;
// }

// int main()
// {
// 	// signal(SIGFPE,helder);

// 	int a = 10;
// 	a /= 0;

// 	while(true)
// 	return 0;
// }


//忽略 默认 自定义
// #include <iostream>
// #include <signal.h>

// void helder(int signo)
// {
// 	std::cout << signo << std::endl;
// }

// int main()
// {
// 	//信号捕捉
// 	// 1.默认
// 	// 2.忽略
// 	// 3.自定义
// 	// signal(2,helder);//自定义动作
// 	// signal(2,SIG_IGN);// ignore: 忽略
// 	// signal(2,SIG_DFL);// default: 默认

// 	while(true)
// 	{
// 		pause();
// 	}
// 	return 0;
// }


// 对2号信号进行屏蔽， 然后获取pending表中保存的屏蔽信号,然后再解除屏蔽
#include <iostream>
#include <signal.h>
#include <unistd.h>

void printpending(sigset_t &set)
{
	std::cout << "curr pending list [" << getpid() << "]: ";

	for(int signo = 31;signo >= 1;signo--)
	{
		if(sigismember(&set,signo))
		{
			std::cout << 1;
		}
		else
		{
			std::cout << "0";
		}
	}
	std::cout << std::endl;
}

void NO_header(int signo)
{

}

int main()
{
	// signal(2,SIG_IGN);
	signal(2,NO_header);

	// 对2号信号进行屏蔽
	// 栈上开辟的空间
	sigset_t block,oblock;
	sigemptyset(&block);
	sigemptyset(&oblock);
	// 添加2号信号
	// 我们有没有把对二号信号的屏蔽，设置进入内核中？ 我们只是在用户栈上设置了block的位图结构
	// 并没有设置进入内核中
	sigaddset(&block,2);
	// 把2号信号设置到屏蔽表里，设置进入内核中
	sigprocmask(SIG_SETMASK,&block,&oblock);

	int cut = 0;
	while(true)
	{
		// 获取pending表中保存的被屏蔽信号
		sigset_t ping;
		sigpending(&ping);
		// 打印
		printpending(ping);
		sleep(1);
		cut++;
		if(cut == 10)
		{
			std::cout << "解除屏蔽" << std::endl;
			sigprocmask(SIG_SETMASK,&oblock,nullptr);
		}
	}
	return 0;
}


